using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;

namespace Sample.Domain
{
    public class PeerReview
    {
        protected PeerReview()
        {
            LinkToReviewers = new List<ReviewerForReview>();
        }

        [Required]
        public virtual Guid Id { get; private set; }

        [Required]
        public virtual string Description { get; set; }

        public virtual IList<ReviewerForReview> LinkToReviewers { get; private set; }
        public virtual Person ConductedFor { get; private set; }
        public virtual DateTime OccurredOn { get; private set; }

        public virtual string Month
        {
            get { return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(OccurredOn.ToLocalTime().Month); }
        }

        public virtual void AddReviewer(Person reviewer, string comments)
        {
            ReviewerForReview link = ReviewerForReview.Create(reviewer, this, comments);
            reviewer.PeerReviewerFor.Add(link);
            LinkToReviewers.Add(link);
        }

        public override int GetHashCode()
        {
            return HashCodeGenerator.GenerateHashCode(Id);
        }

        public override bool Equals(object obj)
        {
            return this.IsEqual(obj);
        }

        public static PeerReview Create(string description, Person reviewee, DateTime occurredOn)
        {
            return Create(description, reviewee, new List<ReviewerForReview>(), occurredOn);
        }

        public static PeerReview Create(string description, Person reviewee, IList<ReviewerForReview> reviewers,
                                 DateTime occurredOn)
        {
            var review = new PeerReview
                             {
                                 Description = description,
                                 ConductedFor = reviewee,
                                 OccurredOn = occurredOn.ToUniversalTime()
                             };

            foreach (ReviewerForReview link in reviewers)
            {
                review.AddReviewer(link.Reviewer, link.Feedback);
            }

            return review;
        }
    }
}